
<template>

  <FormItem
      v-if="
      !(record.options.hidden === true) &&
        ( [
          'input',
          'textarea',
          'date',
          'time',
          'datePicker',
          'number',
          'radio',
          'checkbox',
          'select',
          'rate',
          'switch',
          'slider',
          'uploadImg',
          'uploadFile',
          'cascader',
          'state'
        ].includes(record.type) || customList.includes(record.type) ) && dynamicVisibleItem && !(record.type == 'select' && renderPreview &&  record.options.previewHidden )
    "
      :label="formConfig.labelWidth > 0 ? record.label : null "
      :rules="recordRules"
      :prop="record.model"
      :id="record.model" :name="record.model"
  >

    <BaseItem
        :models="models"
        :formConfig="formConfig"
        :renderPreview="renderPreview"
        :record="record"
        :disabled="disabled"
        @forceUpdate="forceUpdate"
        :isDragPanel="isDragPanel"
    />


  </FormItem>


  <FormItem
      :id="record.model" :name="record.model"
      v-else-if="(record.type === 'batch' || record.type === 'editor') && dynamicVisibleItem"
      :label="!record.options.showLabel ? '' : record.label" :label-width="record.options.showLabel ? null : '0'"
  >

    <TableBatch
        v-model="models[record.model]"
        v-if="record.type === 'batch'"
        ref="TableBatch"
        :renderPreview="renderPreview"
        :models="models"
        :style="`width:${record.options.width}`"
        :record="record"
        :config="formConfig"
        :parentDisabled="disabled"
        @change="handleChange($event, record.model)"

    />

  </FormItem>


  <FormItem
      v-else-if="record.type === 'button' && dynamicVisibleItem"
      :style="{ 'textAlign': record.options.textAlign }"
  >
    <Button
        :disabled="disabled || record.options.disabled"
        :type="record.options.type"
        @click="buttonClick"
        v-text="record.label"
        :size="formConfig ? formConfig.size : 'mini'"
    ></Button>
  </FormItem>


  <div class="form-label" v-else-if="record.type === 'text' && dynamicVisibleItem "
       :style="{ textAlign: record.options.textAlign }">
    <label
        :class="{ 'is-required': record.options.showRequiredMark || showRequiredMark }"
        v-text="record.label"
    ></label>
  </div>

  <div class="form-label" v-else-if="record.type === 'alert' && dynamicVisibleItem "
       :style="{ textAlign: (record.options.center ? 'center' : 'left') }">
    <Alert
        :type="record.options.type"
        :closable="record.options.closable"
        :size="formConfig.size"
        :show-icon="record.options.showIcon">
      {{ record.options.title }}
      <span slot="desc" v-if="record.options.description">
            {{ record.options.description }}
          </span>
      <span slot="close" v-if="record.options.closeText">
            {{ record.options.closeText }}
          </span>

    </Alert>
  </div>

  <div
      :id="record.model" :name="record.model"
      v-else-if="record.type === 'html' && dynamicVisibleItem"
      v-html="record.options.defaultValue"
  ></div>

  <div v-else-if="dynamicVisibleItem">

    <Divider
        v-if=" record.type === 'divider' && record.label !== '' && record.options.orientation "
        :orientation="record.options.orientation"
        :type="record.options.direction ? record.options.direction : 'horizontal'"
        :size="formConfig.size"
    >
      {{ record.options.direction == 'horizontal' ? record.label : '' }}
    </Divider>
    <Divider v-else-if="record.type === 'divider' && record.label !== ''"
             :type="record.options.direction ? record.options.direction : 'horizontal'"
             :size="formConfig.size">
      {{ record.options.direction == 'horizontal' ? record.label : '' }}
    </Divider>
    <Divider v-else-if="record.type === 'divider' && record.label === ''"
             :type="record.options.direction ? record.options.direction : 'horizontal'"
             :size="formConfig.size"/>
  </div>
</template>
<script>
import TableBatch from './table';
import BaseItem from './base';

import {dynamicFun} from '../utils';

export default {
  name: 'iFormItem',
  data() {
    return {
      checkList: [],

    };
  },
  props: {

    record: {
      type: Object,
      required: true,
    },

    formConfig: {
      type: Object,
      default: () => ({
        labelWidth: 120,
      }),

    },

    models: {
      type: Object,
      required: true,
    },
    disabled: {
      type: Boolean,
      default: false,
    },

    renderPreview: {
      type: Boolean,
      default: false,
    },

    isDragPanel: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    TableBatch, BaseItem,
  },
  watch: {
    checkList: {
      handler(val, oldVal) {

        this.$set(this.models, this.record.model, val);
      },
      deep: true,
    },
  },
  inject: {
    customComponents: {
      from: 'customC',
      default: () => [],
    },
  },
  computed: {
    customList() {
      if (this.customComponents) {
        return this.customComponents.map(item => item.type);
      } else {
        return [];
      }
    },
    showRequiredMark() {

      const fstr = this.record.options.showRequiredMarkScript;
      if (!fstr) {
        return false;
      }

      const mark = dynamicFun(fstr, this.models);

      return mark;
    },

    dynamicVisibleItem() {
      if (this.isDragPanel) {
        return true;
      }

      if (!this.record.options || !this.record.options.dynamicVisible) {
        return true;
      }
      if (!this.record.options.dynamicVisibleValue) {
        return true;
      }
      let fstr = this.record.options.dynamicVisibleValue;

      const func = dynamicFun(fstr, this.models);
      return func;
    },
    recordRules() {

      if (this.isDragPanel || this.renderPreview || !this.record.rules || this.record.rules.length == 0) {
        return null;
      }
      let rules = this.record.rules;


      const isRequire = rules[0].required;


      let type_ = 'string';
      if (this.record.type == 'number' || this.record.type == 'rate' || this.record.type == 'slider') {
        type_ = 'number';
      } else if (this.record.type == 'checkbox' || this.record.type == 'cascader'
          || (this.record.type == 'select' && this.record.options.multiple)) {
        type_ = 'array';
      } else if (this.record.type == 'date' || this.record.type == 'datePicker') {
        type_ = 'date';
      } else if (this.record.type == 'switch') {
        type_ = 'boolean';
      }


      for (var i = 0; i < rules.length; i++) {
        const t = rules[i];

        t.required = isRequire;
        if (t.vtype == 1 || t.vtype == 2) {
          t.validator = this.validatorFiled;
        }

        if (t.required && (this.record.type == 'input' || this.record.type == 'textarea')) {
          t.whitespace = true;
        }


        if (!t.trigger) {
          t.trigger = 'change';
        }

        t.type = type_;

      }



      if (this.record.type == 'batch') {
        rules.push({vtype: 3, trigger: 'change', validator: this.validatorFiled, message: '待完善'});
      }


      return rules;

    },
  },
  methods: {
    validatorFiled(rule, value, callback) {


      if (rule.vtype == 1) {

        if (!rule.pattern) {
          callback();
          return;
        }

        var patt1 = new RegExp(rule.pattern);


        if (patt1.test(value)) {
          callback();
        } else {
          callback(new Error(rule.message));
        }

        return;
      } else if (rule.vtype == 2) {

        const script = rule.script;


        const fvalue = dynamicFun(script, this.models);

        if (!fvalue) {
          callback(new Error(rule.message));
        } else {
          callback();
        }


      } else if (rule.vtype == 3) {

        if (!this.$refs.TableBatch) {
          callback();

        } else {
          const v = this.$refs.TableBatch.validatorRule();
          if (v) {
            callback();
          } else {
            callback(new Error(rule.message));
          }

        }

      }


    },
    forceUpdate() {
      this.$emit('forceUpdate');
    },
    handleChange(value, key) {

      this.$emit('change', value, key);

    },

    buttonClick() {
      if (this.record.type != 'button' || !this.record.options.dynamicFun) {
        return;
      }

      dynamicFun(this.record.options.dynamicFun, this.models);

    },
  },
  mounted() {

    if (this.models[this.record.model]){
      return;
    }

    const defaultValue = this.record.options.defaultValue;
    if (defaultValue != null) {
      if (this.record.type == 'checkbox') {
        this.checkList = defaultValue;
      } else {
        this.models[this.record.model] = defaultValue;
      }
    }

  },
};
</script>
